package com.frank.loadinglibrary.common.element;

import com.frank.loadinglibrary.base.baseanimations.BaseAnimationController;
import com.frank.loadinglibrary.base.baseelement.BaseElement;
import com.frank.loadinglibrary.base.baseelement.IComponentCallback;
import com.frank.loadinglibrary.utils.OverWatchViewItem;
import ohos.agp.animation.AnimatorGroup;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.render.Canvas;
import ohos.agp.utils.Color;
import ohos.agp.utils.Point;

import java.util.ArrayList;

public class OverWatchElement extends BaseElement implements BaseAnimationController.IAnimationController<AnimatorGroup> {
    //六边形与六边形之间的间距与长度比，用于计算六边形边距
    public static final int OFFSET_SCALE = 20;
    //中心点坐标
    private float mCenterX, mCenterY;
    private ArrayList<OverWatchViewItem> items = new ArrayList<>();
    OverWatchParams params;

    public OverWatchElement(OverWatchParams param,
                            IComponentCallback call) {
        this.params = param;
        this.callback = call;
    }

    @Override
    public BaseAnimationController.IAnimationController<AnimatorGroup> initAnimationController() {
        return this;
    }

    @Override
    public void draw(Canvas canvas) {
        super.draw(canvas);

        mCenterX = getWidth() / 2;
        mCenterY = getHeight() / 2;
        //先以中心点+边缘6个六边形中心点构建一个新的六边形，计算六边形的长度
        if (params.mViewLength <= 0) {
            params.mViewLength = Math.min(getWidth() - params.spacing * 2, getHeight() - params.spacing * 2) / 3;
        }
        initViewItems();
        for (OverWatchViewItem item : items) {
            item.drawViewItem(canvas);
        }
    }

    @Override
    public ArrayList<AnimatorGroup> onCreateAnimators() {
        AnimatorGroup mPlayAnimator = new AnimatorGroup();
        ArrayList<AnimatorValue> animators = new ArrayList<>();
        if (items.isEmpty()) {
            return null;
        }

        for (OverWatchViewItem item : items) {
            animators.add(item.getShowAnimation());
        }
        for (OverWatchViewItem item : items) {
            animators.add(item.getHideAnimation());
        }
        AnimatorGroup.Builder animatorGroupBuilder = mPlayAnimator.build();
        animators.forEach((AnimatorValue animation) -> {
            animatorGroupBuilder.addAnimators(animation);
        });
        ArrayList<AnimatorGroup> group = new ArrayList<>();
        mPlayAnimator.setLoopedCount(-1);
        group.add(mPlayAnimator);
        return group;
    }

    @Override
    public void onAnimationReset() {
        for (OverWatchViewItem item : items) {
            item.reset();
        }
        if (callback != null) {
            callback.reflushComponent();
        }
    }

    private void initViewItems() {
        if (items == null || items.isEmpty()) {
            Point[] points = getHexagonPoints(new Point(mCenterX, mCenterY), params.mViewLength);
            int itemLength = (int) (params.mViewLength / 2);
            int offsetLength = itemLength / OFFSET_SCALE;
            int i = 0;
            for (Point point : points) {
                items.add(new OverWatchViewItem(callback, new Color(Color.getIntColor(params.colorPalette[i])), point, itemLength - offsetLength, params.durtion));
                i++;
            }
            if (!isAnimationRunning()) {
                startAnimators();
            }
        }
    }

    /**
     * @param centerPoint
     * @param length
     * @return 7个点 中心点+6个中心点
     */
    private static Point[] getHexagonPoints(Point centerPoint, float length) {

        Point[] points = new Point[7];
        float height = (float) (Math.sin(Math.PI / 3) * length);
        points[0] = new Point(centerPoint.getPointX() - length / 2, centerPoint.getPointY() - height);
        points[1] = new Point(centerPoint.getPointX() + length / 2, centerPoint.getPointY() - height);
        points[2] = new Point(centerPoint.getPointX() + length, centerPoint.getPointY());
        points[3] = new Point(centerPoint.getPointX() + length / 2, centerPoint.getPointY() + height);
        points[4] = new Point(centerPoint.getPointX() - length / 2, centerPoint.getPointY() + height);
        points[5] = new Point(centerPoint.getPointX() - length, centerPoint.getPointY());
        points[6] = centerPoint;
        return points;

    }


    /**
     * 构建者
     */
    public static class OverWatchBuild {

        private final int value_7 = 7;
        OverWatchParams params;
        IComponentCallback call;
        private static final String COLOR_WHITE = "#FFFFFF";

        public OverWatchBuild(IComponentCallback c) {
            call = c;
            params = new OverWatchParams();
            //设置默认为白色
            params.colorPalette = new String[7];
            for (int i = 0; i < value_7; i++) {
                params.colorPalette[i] = COLOR_WHITE;
            }
        }


        public OverWatchBuild setDurtion(int dur) {
            params.durtion = dur;
            return this;
        }

        public OverWatchBuild setColorPalette(String[] colors) {
            for (int i = 0; i < value_7; i++) {
                if (colors == null) {
                    params.colorPalette[i] = COLOR_WHITE;
                } else {
                    //交叉给颜色
                    params.colorPalette[i] = colors[i % colors.length];
                }
            }
            return this;
        }

        public OverWatchBuild setSpace(float space) {
            params.spacing = space;
            return this;
        }

        public OverWatchElement build() {
            return new OverWatchElement(params, call);
        }
    }

    /***
     * 可配置参数类
     */
    public static class OverWatchParams {
        //配置颜色数组
        protected String[] colorPalette;

        //配置半径
        private float mViewLength = 0;
        //配置水平间隔
        private float spacing = 0;

        //设置动画时间基数
        private int durtion;

    }
}
